<?php
/*
 * File: User.php
 * Created Time: 2024-05-29 11:27:52 am
 * Author: WangYuQiang && WangpeiGang (719404171@qq.com)
 * -----
 * Last Modified: 2025-07-21 2:34:47 pm
 * Modified By: WangYuQiang (719404171@qq.com>)
 * -----
 * Copyright (c) 2024 成都睿創科技有限公司
 */


namespace App\Models;

use App\Extend\Com;
use DateTimeInterface;
use Laravel\Cashier\Billable;//Cashier支付
use Laravel\Passport\HasApiTokens;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Builder;
use App\Http\Controllers\Api\BaseController;
use Illuminate\Foundation\Auth\User as Authenticatable;
/**
 * App\Models\User
 *
 */
class User extends Base
{

    protected $table = 'users';           //定义用户表名称
    protected $primaryKey = "user_id";          //定义用户表主键
    protected $hidden = ['user_password'];      //不返回用戶密碼

    use Notifiable,HasApiTokens,Billable;

    /**
     * 自定义的密码字段, 无此，对于密码字段名不为password的登录时将出现密码不存在
     * @return string
     */
    public function getAuthPassword() {
        return $this->user_password;        // 一定要返回加密了的密码
    }

    /**
     * 为数组 / JSON 序列化准备日期。
     */
    protected function serializeDate(DateTimeInterface $date){
        return $date->format($this->dateFormat ?: 'Y-m-d H:i:s');
    }


/*********************************************************关联**********************************************************************/
    /**
     * 关联用户优惠券
     */
    public function getUserExchange(){
        return $this->hasMany('App\Models\UserExchange','user_id','user_id');
    }

    /**
     * 关联用户收藏
     */
    public function getUserCollect(){
        return $this->hasMany('App\Models\UserCollect','user_id','user_id');
    }

    /**
     * 关联用户钱包记录
     */
    public function getUserWallet(){
        return $this->hasMany('App\Models\UserWalletRecord','user_id','user_id');
    }

    /**
     * 关联用户积分记录
     */
    public function getUserIntegral(){
        return $this->hasMany('App\Models\UserIntegralRecord','user_id','user_id');
    }

/*********************************************************全局作用域注册**********************************************************************/

    protected static function boot(){
        parent::boot();
	    static::addGlobalScope('user_status', function (Builder $builder) {
		    return $builder->where('users.user_status',  '<>', -1);
	    });
    }


/*********************************************************admin**********************************************************************/


    /**
     * 獲取用戶列表
     * @param $data
     * @return array
     */
    public function getUserListWeb($data){
        $limit = $data['limit'];
        $page = ($data['page'] - 1) * $limit;
        $where[] = array('user_status','<>',-1);
        $where[] = array('user_id','<>',1);//不顯示等於1的用戶
        if(isset($data['user_status']) && (!empty($data['user_status']) || is_numeric($data['user_status']))){
            $where['user_status'] = $data['user_status'];
        }
        $datas['data'] = $this->where($where)
            ->where(function ($query) use ($data){
                if(!empty($data['multi'])){
                    $query->whereRaw('(
                                 concat(
                                 COALESCE(user_phone, ""),
                                 COALESCE(user_name, ""),
                                 COALESCE(user_email, ""),
                                 COALESCE(user_number, "")) like "%' . $data['multi'] . '%")');
                }
            })
            ->offset($page)->limit($limit)
            ->orderBy('user_id','desc')
            ->get()->toArray();
        $datas['count'] = $this->where($where)
            ->where(function ($query) use ($data){
                if(!empty($data['multi'])){
                    $query->whereRaw('(
                                 concat(
                                 COALESCE(user_phone, ""),
                                 COALESCE(user_name, ""),
                                 COALESCE(user_email, ""),
                                 COALESCE(user_number, "")) like "%' . $data['multi'] . '%")');
                }
            })->count();
        return $this->success(__('web.success'),$datas);
    }

    /**
     * 新增用戶
     * @param $data
     * @return array
     */
    public function addUserWeb($data){
        $userItem = $this->where(function ($query) use ($data){
                if(!empty($data["user_phone"]) && !empty($data['area_code'])){
                    $query->where("user_phone", $data["user_phone"])->where('area_code',$data['area_code'])->where('user_status','<>',-1);
                }
            })->orWhere(function ($q) use ($data){
                if (!empty($data['user_email'])){
                    $q->orWhere("user_email", $data["user_email"])->where('user_status','<>',-1);
                }
            })->first();
        if (!empty($userItem['user_phone']) && ($userItem['user_phone'] == $data["user_phone"])) {
            return $this->error(__('web.phone_exist'));
        }else if(!empty($userItem['user_email']) && ($userItem['email'] == $data['user_email'])){
            return $this->error(__('web.email_exist'));
        }
        DB::beginTransaction();
        $user = new User();
        $user->user_number = time().rand(100001,999999).$user->user_id;
        $user->user_email = $data["user_email"];
        $user->user_phone = $data["user_phone"];
        $user->user_password = bcrypt($data["user_password"]);
        $user->user_sex = $data["user_sex"];
        $user->area_code = $data["area_code"];
        $user->user_name = $data["user_name"];
        $user->user_integral = $data["user_integral"];
        $user->user_balance = $data["user_balance"];
        $user->user_avatar = config('services.basics.user_avatar');
        $user->created_at = self::getDate();
        $res = $user->save();
        if ($res) {
            DB::commit();
            return $this->success(__('web.add_success'));
        } else {
            DB::rollBack();
            return $this->error(__('web.add_fail'));
        }
    }

    /**
     * 編輯用戶
     * @param $data
     * @param $admin_id
     * @return array
     */
    public function editUserWeb($data,$admin_id){
        $userItem = $this->where(function ($query) use ($data){
            if(!empty($data["user_phone"]) && !empty($data['area_code'])){
                $query->where("user_phone", $data["user_phone"])->where('area_code',$data['area_code'])->where('user_status','<>',-1)->where('user_id','<>',$data['user_id']);
            }
        })->orWhere(function ($q) use ($data){
                if (!empty($data['user_email'])){
                    $q->orWhere("user_email", $data["user_email"])->where('user_status','<>',-1)->where('user_id','<>',$data['user_id']);
                }
            })->first();
        if (!empty($userItem['user_phone']) && ($userItem['user_phone'] == $data["user_phone"])) {
            return $this->error(__('web.phone_exist'));
        }else if(!empty($userItem['user_email']) && ($userItem['email'] == $data['user_email'])){
            return $this->error(__('web.email_exist'));
        }

        $userInfo = $this->where('user_id',$data['user_id'])->select('user_integral_all','user_integral','user_balance')->first();
        $admin = Admins::where('admin_id',$admin_id)->select('username','admin_id')->first();
        DB::beginTransaction();
        $integralNumber = 0;
        $AddIntegralLog = true;
        $AddBalanceLog = true;
        if($userInfo['user_integral'] != $data['user_integral']){
            $integralNumber = $data['user_integral'] - $userInfo['user_integral'];
            if($integralNumber > 0 && $integralNumber != 0){
                $str = 'ID為'.$data['user_id'].'的用戶  +'.$integralNumber.'積分';
                $en_str =  'User with ID'.$data['user_id'].'+'.$integralNumber.'points';
                $mode = 1;
            }else if($integralNumber < 0 && $integralNumber != 0){
                $str = 'ID為'.$data['user_id'].'的用戶  -'.$integralNumber.'積分';
                $en_str = 'User with ID'.$data['user_id'].'- '.$integralNumber.'points';
                $mode = 2;
            }
            $integralInfo = [
                'admin_name' => $admin['username'],
                'admin_id' => $admin['admin_id'],
                'activity_type' => 1,
                'activity_mode' => $mode,
                'activity_value' => $str,
                'en_activity_value' => $en_str,
                'created_at' => self::getDate()
            ];
            $AddIntegralLog = ActivityLog::insert($integralInfo);
        }
        if($userInfo['user_balance'] != $data['user_balance']){
            $balanceNumber = $data['user_balance'] - $userInfo['user_balance'];
            if($balanceNumber > 0 && $balanceNumber != 0){
                $message = 'ID為'.$data['user_id'].'的用戶  +'.$balanceNumber.'餘額';
                $en_message = 'User with ID '.$data['user_id'].'+'.$balanceNumber.'balance';
                $activity_mode = 1;
            }else if($balanceNumber < 0 && $balanceNumber != 0){
                $message = 'ID為'.$data['user_id'].'的用戶  '.$balanceNumber.'餘額';
                $en_message =  'User with ID '.$data['user_id'].'-'.$balanceNumber.'balance';
                $activity_mode = 2;
            }
            $balanceInfo = [
                'admin_name' => $admin['username'],
                'admin_id' => $admin['admin_id'],
                'activity_type' => 2,
                'activity_mode' => $activity_mode,
                'activity_value' => $message,
                'en_activity_value' => $en_message,
                'created_at' => self::getDate()
            ];
            $AddBalanceLog = ActivityLog::insert($balanceInfo);
        }
        if($AddIntegralLog && $AddBalanceLog){
            if($integralNumber > 0){
                $data['user_integral_all'] = $userInfo['user_integral_all'] + $integralNumber;
            }
            $editUserStatus = $this->where('user_id',$data['user_id'])->update($data);
            if($editUserStatus){
                DB::commit();
                return $this->success(__('web.edit_success'));
            }else{
                DB::rollBack();
                return $this->error(__('web.edit_fail'));
            }
        }else{
            DB::rollBack();
            return $this->error(__('web.edit_fail'));
        }
    }

    /**
     * 刪除用戶
     * @param $userID
     * @return array
     */
    public function deleteUserWeb($userID){
        $data = self::softDelete('users','user_id',$userID,'user_status',-1);
        if($data){
            return $this->success(__('web.delete_success'));
        }else{
            return $this->error(__('web.delete_fail'));
        }
    }

    /**
     * 獲取用戶消費分析
     * @param $data
     * @param $language
     * @return array
     */
    public function getUserAnalysisWeb($data,$language){
        $limit = $data['limit'];
        $page = ($data['page'] - 1) * $limit;

        $time = [];
        $type = $data['type'];

        if(!empty($data['time'])){
            $time['start_time'] = $data['time'][0];
            $time['end_time'] = $data['time'][1];
        }

        if($type == 0){
            $fieldName = 'order_money';
        }else if($type == 1){
            $fieldName = 'order_number';
        }else{
            $fieldName = 'order_money';
        }

        $where[] = array('order.payment_status', '>=', 3);
        $where[] = array('order.order_status', '=', 1);
        $where[] = array('users.user_status', '=', 1);
        if(!empty($data['user_name'])){
            $where[] = array('users.user_name', 'like', '%' . $data['user_name'] . '%');
        }

        //獲取用戶消費總金額和消費次數
        $orderMoney = Order::join('users','users.user_id','=','order.user_id')
            ->where($where)
            ->where(function ($query) use ($time){
                if(!empty($time) && $time['start_time'] != ''){
                    return $query->whereBetween('order.payment_at',$time);
                }
            })->select('order.user_id','order.order_type',DB::raw('SUM(order.order_money) as order_money'),DB::raw('COUNT(order.order_id) as order_number'),'users.user_name','users.user_integral_all')
            ->groupBy("order.user_id")
            ->get()->toArray();
        $last_names = array_column($orderMoney,$fieldName);
        array_multisort($last_names,SORT_DESC,$orderMoney);
        $datas['data'] = array_slice($orderMoney,$page,$limit);
        $datas['count'] = count($orderMoney);
        $member = UserMember::get()->toArray();
        for($i=0;$i<count($datas['data']);$i++){
//            $wheres[] = array('member_start','<=',$datas['data'][$i]['user_integral_all']);
//            $wheres[] = array('member_end','>=',$datas['data'][$i]['user_integral_all']);
//            $member = UserMember::where($wheres)->first();
            $userMember = $this->levelMember($datas['data'][$i]['user_integral_all'],$member);
            if($datas['data'][$i]['order_type']==2){
               $datas['data'][$i]['member_name'] = '——';
            }else{
               $datas['data'][$i]['member_name'] = current($userMember)[$language.'member_name'];
            }
//            $datas['data'][$i]['member_name'] = $member[$language.'member_name'];
//            $wheres =array();
        }
        return $this->success(__('web.success'),$datas);
    }

    public function levelMember($score,$filter){
        $half = floor(count($filter) / 2);
        if($score <= $filter[$half - 1]['member_end']){
            $filter = array_slice($filter,0,$half);
        }else{
            $filter = array_slice($filter,$half,count($filter));
        }

        if(count($filter) != 1){
            $filter = $this->levelMember($score,$filter);
        }
        return $filter;
    }




/**********************************************************api**********************************************************************/



    /**
     * @param $data
     * @return array
     * 獲取用戶信息
     */
    public function getUsersInfo($user_id){
        $language = app('global_language') == "en" ? "en_" : "";
        $where[] = array('user_id','=',$user_id);
        $results = $this ->where($where)->select('*')->first();
        if (empty($results['user_code'])) {
            $CodeInfo=(string)$user_id;
            $BaseController = new BaseController();
            $Usercode=$BaseController->getQRCode($CodeInfo);
            $results['user_code']=$Usercode['results'];
        }
        //不顯示密碼
        unset($results['user_password']);
        if(!empty($results)){
            //超出最高分級時使用最高的等級
            $maxmember = UserMember::max('member_end');
            if($results['user_integral_all'] > $maxmember){
                $memberinfo = UserMember::orderBy('member_end', 'desc')->first();
                //显示下个等级
                $results['next_name'] = $memberinfo[$language.'member_name'];
            } else {
                $maxLevel = UserMember::where('member_status','=',1)->orderBy('member_end', 'desc')->first();
                if($results['user_integral_all'] <= $maxLevel->member_end) {
					$member = UserMember::where('member_status','=',1)->get()->toArray();
					$memberinfo = current($this->levelMember($results['user_integral_all'],$member));
                    //显示下个等级
                    $results['next_name'] = UserMember::where('member_id',$memberinfo['member_id']+1)->first()[$language.'member_name'] ??
                        UserMember::where('member_id',$memberinfo['member_id'])->first()[$language.'member_name'];

                }else{
                    //直接使用設置的最高等级
                    $results['next_name'] = $maxLevel[$language . 'member_name'];
                    $memberinfo = $maxLevel;
                }
                // $this->LogInfo('memberinfo' , $memberinfo , 'memberinfo' , true);//开启日志记录
            }
            $results['member_name'] = $memberinfo[$language.'member_name'];
            $results['memberGrade'] = $memberinfo['member_id'];
            $results['member_start'] = $memberinfo['member_start'];
            $results['member_end'] = $memberinfo['member_end'];
            return $this->success( __('api.list_success'), $results);
        }else{
            return $this->success( __('api.list_null'), $results);
        }
    }




    /**
     * @param $data
     * @return array
     * 修改用戶信息
     */
    public function UpdateUsers($user_id , $data){
        DB::beginTransaction();
        try {
            if(!empty($data['user_password'])){
                $data['user_password']=bcrypt($data['user_password']);
            }
            $effects = $this->where('user_id',$user_id)->update($data);
            if(!empty($effects)){
                // $this->LogInfo('多语言日志' , $results , 'lang' , true);//开启日志记录
                DB::commit();
                return $this->success( __('api.edit_success'));
            }else{
                DB::rollBack();
                return $this->error( __('api.edit_fail'));
            }
        }catch (\Exception $e) {
            DB::rollBack();
            return $this->error( __('api.edit_fail') , $e->getMessage());
        }

    }


    /**
     * @param $data
     * @return mixed
     * 修改綁定手機號
     */
    public function UpdatePhone($user_id , $data){
        DB::beginTransaction();
        try {
            $effects = $this->where('user_id',$user_id)
                            ->update([
                                     'user_phone'=>$data['user_phone'],
                                     'area_code'=>$data['area_code'],
                                     'updated_at'=>date('Y-m-d H:i:s')
                                    ]);
            if(!empty($effects)){
                // $this->LogInfo('多语言日志' , $results , 'lang' , true);//开启日志记录
                DB::commit();
                return $this->success( __('api.edit_success'));
            }else{
                DB::rollBack();
                return $this->error( __('api.edit_fail'));
            }
        }catch (\Exception $e) {
            DB::rollBack();
            return $this->error( __('api.edit_fail') , $e->getMessage());
        }
    }



/**************************************************common(api和admin共用)***********************************************************/


    /**
     * @param $data
     * @return array
     * 獲取用戶快照
     */
    public function UserSnapshot($user_id){
        $where[] = array('user_id','=',$user_id);
        $effects = $this ->where($where)->select('*')->first();
        //轉json
        return  json_encode($effects);
    }




}
